package com.pig4cloud.pigx.contract.api.v1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.customize.api.enums.AbnormalEnum;
import com.pig4cloud.pigx.common.customize.api.util.OpenApiUtil;
import com.pig4cloud.pigx.common.customize.security.utils.SecurityUtil;
import com.pig4cloud.pigx.common.security.service.PigxUser;
import com.pig4cloud.pigx.contract.api.v1.service.TradeServiceV1;
import com.pig4cloud.pigx.contract.api.v1.utils.OpenApiContractUtilsV1;
import com.pig4cloud.pigx.contract.entity.ContractTrade;
import com.pig4cloud.pigx.contract.enums.ContractOrderEnum;
import com.pig4cloud.pigx.contract.mapper.ContractTradeMapper;
import com.pig4cloud.pigx.contract.open.api.dto.OpenApiLatelyTradeDTOV1;
import com.pig4cloud.pigx.contract.open.api.dto.OpenApiTradeHistoryDTOV1;
import com.pig4cloud.pigx.contract.open.api.vo.OpenApiLatelyTradeVOV1;
import com.pig4cloud.pigx.contract.open.api.vo.OpenApiTradeHistoryVOV1;
import com.pig4cloud.pigx.contract.utils.ContractUtils;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;

/**
 */
@Service
@AllArgsConstructor
public class TradeServiceImplV1 extends ServiceImpl<ContractTradeMapper, ContractTrade> implements TradeServiceV1 {

	private final static Integer DEFAULT_LIMIT = 500;

	private final static Integer MAX_LIMIT = 1000;

	private final OpenApiContractUtilsV1 apiContractUtils;

	private final ContractUtils contractUtils;

	@Override
	public R<List<OpenApiLatelyTradeVOV1>> getLatelyTrade(OpenApiLatelyTradeDTOV1 dto) {
		// 参数为空异常
		if (dto.getSymbolName() == null || "".equals(dto.getSymbolName())) {
			throw OpenApiUtil.getError(AbnormalEnum.MSG.PARAM_EMPTY, "symbolName");
		}
		// 币对校验
		apiContractUtils.getSymbolMongo(dto.getSymbolName());
		// 查询数量限制
		if (dto.getLimit() != null && dto.getLimit() > MAX_LIMIT) {
			throw OpenApiUtil.getError(AbnormalEnum.MSG.UNKNOWN_ORDER_COMPOSITION, "limit");
		}
		// 未指定查询数量 设置默认查询数量
		if (dto.getLimit() == null) {
			dto.setLimit(DEFAULT_LIMIT);
		}
		try {
			List<ContractTrade> list = baseMapper.selectList(new QueryWrapper<ContractTrade>() {{
				eq("symbol_name", dto.getSymbolName());
				if (dto.getTime() != null) {
					lt("create_time", Instant.ofEpochMilli(dto.getTime()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
				}
				orderByDesc("create_time");
				last("limit " + dto.getLimit());
			}});
			List<OpenApiLatelyTradeVOV1> vo = new ArrayList<>();
			list.forEach(e -> {
				OpenApiLatelyTradeVOV1 tradeVO = new OpenApiLatelyTradeVOV1();
				BeanUtils.copyProperties(e, tradeVO);
				tradeVO.setTime(e.getCreateTime().toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
				contractUtils.setScaleBySymbol(tradeVO, dto.getSymbolName());
				vo.add(tradeVO);
			});
			return R.ok(vo);
		} catch (Exception e) {
			throw OpenApiUtil.getError(AbnormalEnum.MSG.DISCONNECTED);
		}
	}

	@Override
	public R<Page<OpenApiTradeHistoryVOV1>> getUserTradeHistory(OpenApiTradeHistoryDTOV1 dto) {
		// 币对校验
		apiContractUtils.getSymbolMongo(dto.getSymbolName());
		// 获取用户信息
		// 获取当前登录人
		PigxUser user = SecurityUtil.getLoginUserNotNull();
		if (user == null || user.getId() == null) {
			throw OpenApiUtil.getError(AbnormalEnum.MSG.OPTIONS_USER_NOT_FOUND);
		}
		// 分页默认值
		if (dto.getCurrent() == null) {
			dto.setCurrent(1L);
		}
		if (dto.getSize() == null) {
			dto.setSize(10L);
		}
		Page<ContractTrade> page = new Page<>();
		page.setCurrent(dto.getCurrent());
		page.setSize(dto.getSize());
		// 查询
		Page<ContractTrade> selectPage = baseMapper.selectPage(page, new QueryWrapper<ContractTrade>() {{
			eq("symbol_name", dto.getSymbolName());
			eq("user_id", user.getId());
			if (dto.getStartTime() != null) {
				ge("create_time", Instant.ofEpochMilli(dto.getStartTime()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
			}
			if (dto.getEndTime() != null) {
				le("create_time", Instant.ofEpochMilli(dto.getEndTime()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
			}
			orderByDesc("create_time");
		}});
		// 类型转换 + 字典项翻译 + 精度设置
		Page<OpenApiTradeHistoryVOV1> historyPage = new Page<>();
		BeanUtils.copyProperties(selectPage, historyPage);
		List<OpenApiTradeHistoryVOV1> list = new ArrayList<>();
		selectPage.getRecords().forEach(e -> {
			OpenApiTradeHistoryVOV1 vo = new OpenApiTradeHistoryVOV1();
			BeanUtils.copyProperties(e, vo);
			vo.setTime(e.getCreateTime().toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
			vo.setSide(ContractOrderEnum.Side.findName(vo.getSide()));
			vo.setOrderType(ContractOrderEnum.Type.findName(vo.getOrderType()));
			vo.setOperationType(ContractOrderEnum.OperationType.findName(vo.getOperationType()));
			contractUtils.setScaleBySymbol(vo, vo.getSymbolName());
			list.add(vo);
		});
		historyPage.setRecords(list);
		return R.ok(historyPage);
	}

}
